package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.worldboss.WorldBoss;
import com.motu.monstercity.server.game.commondata.worldboss.WorldBossReward;
import com.motu.monstercity.server.game.commondata.worldboss.WorldBossTask;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class WorldBossBaseData {
    private static Logger logger = LoggerFactory.getLogger(WorldBossBaseData.class);

    private static ConcurrentHashMap<Integer, WorldBoss> worldBossMap = new ConcurrentHashMap<>(); // 世界boss主表
    private static CopyOnWriteArrayList<WorldBoss> worldBossDataList = new CopyOnWriteArrayList<>();  // 排序列表 世界Boss
    private static ConcurrentHashMap<Integer, WorldBossReward> worldBossRewardMap = new ConcurrentHashMap<>(); // 世界Boss奖励表
    private static ConcurrentHashMap<Integer, List<WorldBossReward>> worldBossRewardGroupMap = new ConcurrentHashMap<>(); // 世界Boss奖励表 groupId->对应伤害列表
    private static ConcurrentHashMap<Integer, WorldBossTask> worldBossTaskMap = new ConcurrentHashMap<>(); // 世界boss任务表
    private static ConcurrentHashMap<Integer, List<WorldBossTask>> worldBossTaskGroupMap = new ConcurrentHashMap<>(); // 世界boss任务表 groupId->

    // 公共数据初始化
    public static void init(List<Future> futures) {
        futures.add(initWorldBoss());
        futures.add(initWorldBossReward());
        futures.add(initWorldBossTask());
    }
    /**
     * 初始化世界boss主表
     */
    public static Future<Void> initWorldBoss() {
        String table = "world_boss";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, WorldBoss> tmp = new ConcurrentHashMap<>();
                    CopyOnWriteArrayList<WorldBoss> tmp2 = new CopyOnWriteArrayList<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        WorldBoss entity = new WorldBoss(result.getJsonObject(i));
                        tmp.put(entity.getPeriods(), entity);
                        tmp2.add(entity);
                    }
                    worldBossMap = tmp;
                    tmp2.sort(Comparator.comparingInt(WorldBoss::getPeriods));  // 升序
                    worldBossDataList = tmp2;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static WorldBoss getWorldBoss(int id) {
        WorldBoss result = worldBossMap.get(id);
        if (result == null) {
            logger.error("getWorldBoss error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, WorldBoss> getWorldBossMap() { return worldBossMap; }


    /**
     * 根据开服天数获取世界BOSS（支持循环取值）
     * @param serverDays 开服天数（从1开始）
     * @param offsetDays 偏移天数（如-2表示提前2天）
     * @return 对应的世界BOSS对象（循环获取）
     */
    public static WorldBoss getWorldBossByDay(int serverDays, int offsetDays) {
        if (worldBossDataList.isEmpty()) {
            logger.error("世界BOSS数据未初始化！");
            return null; // 或抛出异常
        }
        int size = worldBossDataList.size();
        // 计算原始索引 = (开服天数 - 1) - 偏移量
        int rawIndex = serverDays - 1 - offsetDays;
        // 循环处理索引（支持负数和大索引）
        int adjustedIndex = (rawIndex % size + size) % size;
        if (adjustedIndex < 0 ||  adjustedIndex >= size) {
            return null;
        }
        return worldBossDataList.get(adjustedIndex);
    }



    /**
     * 初始化世界Boss奖励表
     */
    public static Future<Void> initWorldBossReward() {
        String table = "world_boss_reward";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, WorldBossReward> tmp = new ConcurrentHashMap<>();
                    ConcurrentHashMap<Integer, List<WorldBossReward>> tmp2 = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        WorldBossReward entity = new WorldBossReward(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);
                        tmp2.computeIfAbsent(entity.getGroupId(), k -> new ArrayList<>()).add(entity);
                    }
                    worldBossRewardMap = tmp;
                    // 内部按照伤害排序
                    tmp2.forEach((groupId, list) -> {
                        // 创建新List并排序（不影响原始配置数据）
                        List<WorldBossReward> sortedList = new ArrayList<>(list);
                        sortedList.sort(Comparator.comparingLong(WorldBossReward::getPersonalDamage));
                        // 存入ConcurrentHashMap
                        tmp2.put(groupId, sortedList);
                    });
                    worldBossRewardGroupMap = tmp2;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static WorldBossReward getWorldBossReward(int id) {
        WorldBossReward result = worldBossRewardMap.get(id);
        if (result == null) {
            logger.error("getWorldBossReward error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, WorldBossReward> getWorldBossRewardMap() { return worldBossRewardMap; }

    public static List<RewardItem> getWorldBossGroupReward(int groupId,long damage,long totalEarn){
        List<WorldBossReward> worldBossRewardList = worldBossRewardGroupMap.get(groupId);
        String rewardString = "";
        long num = 0;
        for (WorldBossReward reward:worldBossRewardList){
            if (reward.getPersonalDamage() <= damage){
                rewardString = reward.getReward();
                num = totalEarn * reward.getEarnReward();
            }else{
                break;
            }
        }
        ArrayList<RewardItem> rewardItems = new ArrayList<>(CommonUtils.takeReawrdItemFromStr(rewardString));
        if (num > 0){
            rewardItems.add(new RewardItem(ItemId.GOLD,num));  // 添加金币赚速奖励
        }
        return rewardItems;
    }
    /**
     * 初始化世界boss任务表
     */
    public static Future<Void> initWorldBossTask() {
        String table = "world_boss_task";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, WorldBossTask> tmp = new ConcurrentHashMap<>();
                    ConcurrentHashMap<Integer, List<WorldBossTask>> tmp2 = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        WorldBossTask entity = new WorldBossTask(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);
                        tmp2.computeIfAbsent(entity.getGroupId(), k -> new ArrayList<>()).add(entity);
                    }
                    worldBossTaskMap = tmp;

                    // 内部按照伤害排序
                    tmp2.forEach((groupId, list) -> {
                        // 创建新List并排序（不影响原始配置数据）
                        List<WorldBossTask> sortedList = new ArrayList<>(list);
                        sortedList.sort(Comparator.comparingLong(WorldBossTask::getPar));
                        // 存入ConcurrentHashMap
                        tmp2.put(groupId, sortedList);
                    });
                    worldBossTaskGroupMap = tmp2;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static WorldBossTask getWorldBossTask(int id) {
        WorldBossTask result = worldBossTaskMap.get(id);
        if (result == null) {
            logger.error("getWorldBossTask error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, WorldBossTask> getWorldBossTaskMap() { return worldBossTaskMap; }


    // 根据伤害获取联盟总奖励
    public static List<RewardItem> getWorldBossTaskReward(int groupId,long damage){
        List<WorldBossTask> worldBossTaskList = worldBossTaskGroupMap.get(groupId);
        List<RewardItem> tmp = new ArrayList<>();
        for (WorldBossTask task:worldBossTaskList){
            if (task.getPar() <= damage){
                tmp.addAll(CommonUtils.takeReawrdItemFromStr(task.getReward()));
            }else{
                break;
            }
        }
        return tmp;
    }
}
